package com.report.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.zhxu.bs.BeanSearcher;
import cn.zhxu.bs.SearchResult;
import cn.zhxu.bs.operator.Equal;
import cn.zhxu.bs.util.MapUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.report.constants.TagConstants;
import com.report.dto.request.BrowseReq;
import com.report.dto.request.WebMemberCollectReq;
import com.report.dto.response.DownloadReportRes;
import com.report.dto.response.MemberRes;
import com.report.dto.response.WebMemberBrowseRes;
import com.report.dto.response.zu.WeChatMiniReportRes;
import com.report.entity.Browse;
import com.report.entity.Report;
import com.report.entity.Rule;
import com.report.mapper.BrowseMapper;
import com.report.service.IBrowseService;
import com.report.service.IMemberRuleService;
import com.report.service.IMemberService;
import com.report.service.IReportService;
import com.report.utils.LocalDateUtils;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.exception.ResultException;
import com.zmh.framework.redis.RedisCache;
import com.zmh.framework.util.IpKit;
import lombok.AllArgsConstructor;
import org.checkerframework.common.value.qual.ArrayLen;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author summer
 * @since 2024/06/25 14:54:44
 */
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class BrowseServiceImpl extends ServiceImpl<BrowseMapper, Browse> implements IBrowseService {


    private final IReportService reportService;

    @Override
    public void saveBrowse(BrowseReq browseReq) {
        LambdaQueryWrapper<Browse> eq = Wrappers.lambdaQuery(Browse.class).eq(Browse::getMemberId, browseReq.getMemberId()).eq(Browse::getReportId, browseReq.getReportId());
        Browse browse = this.getOne(eq);
        if(ObjectUtil.isNull(browse)) {
            browse = new Browse();
            browse.setMemberId(browseReq.getMemberId());
            browse.setReportId(browseReq.getReportId());
            this.save(browse);
//            Report report = reportService.getById(browseReq.getReportId());
//            report.setBrowseNum(report.getBrowseNum() + 1);
//            reportService.updateById(report);
        }
    }

    private final BeanSearcher beanSearcher;

    @Override
    public Page<WebMemberBrowseRes> findBrowseList(WebMemberCollectReq webMemberCollectReq) {

        Page<WebMemberBrowseRes> webMemberBrowseRes = new Page<>(webMemberCollectReq.getPageNum(), webMemberCollectReq.getPageSize());
        Map<String, Object> build = MapUtils.builder().page(webMemberCollectReq.getPageNum() - 1, webMemberCollectReq.getPageSize())
                .field(WebMemberBrowseRes::getMemberId, webMemberCollectReq.getMemberId()).op(Equal.class).build();
        SearchResult<WebMemberBrowseRes> search = beanSearcher.search(WebMemberBrowseRes.class, build);
        webMemberBrowseRes.setTotal(search.getTotalCount().longValue());
        webMemberBrowseRes.setRecords(search.getDataList());
        return webMemberBrowseRes;
    }

    private final IMemberService memberService;

    private final IMemberRuleService ruleService;


    @Override
    public void readNum() {
        MemberRes memberRes = memberService.memberInfo();
        Rule rule = ruleService.getById(memberRes.getRuleId());
        //当日浏览数量
        Map<String, Object> build = MapUtils.builder().field(WebMemberBrowseRes::getMemberId, StpUtil.getLoginId()).op(Equal.class)
                .field(WebMemberBrowseRes::getCreateTime).sql("DATE($1) =CURDATE()").build();
        Number number = beanSearcher.searchCount(WebMemberBrowseRes.class, build);
        int downloadDay = number.intValue();

        //当月浏览量量
        Map<String, Object> built = MapUtils.builder().field(WebMemberBrowseRes::getMemberId, StpUtil.getLoginId()).op(Equal.class)
                .field(WebMemberBrowseRes::getCreateTime).sql("MONTH($1) = MONTH(CURDATE())").build();
        Number number1 = beanSearcher.searchCount(WebMemberBrowseRes.class, built);
        int downloadMonth = number1.intValue();


        if(ObjectUtil.isNotEmpty(memberRes)){
            Integer readDay = rule.getReadDay();
            Integer readMonth = rule.getReadMonth();
            if(downloadDay==readDay){
                throw new ResultException("今日权限已用完，可以升级权益");
            }
            if(downloadMonth==readMonth){
                throw new ResultException("当月权限已用完，可以升级权益");
            }
        }else{
            throw new ResultException("会员信息查询失败,请联系客服");
        }
    }

    @Override
    public Integer readDayNum(BrowseReq browseReq) {

        Map<String, Object> build1 = MapUtils.builder().field(WebMemberBrowseRes::getMemberId, browseReq.getMemberId()).op(Equal.class)
                .field(WebMemberBrowseRes::getReportId, browseReq.getReportId()).op(Equal.class).build();
        Number number1 = beanSearcher.searchCount(WebMemberBrowseRes.class, build1);
        if(number1.intValue()> Constants.ZERO){
            return number1.intValue();
        }

        Map<String, Object> build = MapUtils.builder().field(WebMemberBrowseRes::getMemberId,browseReq.getMemberId()).op(Equal.class)
                .field(WebMemberBrowseRes::getCreateTime).sql("DATE($1) =CURDATE()").build();
        Number number = beanSearcher.searchCount(WebMemberBrowseRes.class, build);
        MemberRes memberRes = memberService.getMemberById(browseReq.getMemberId());
       if(memberRes.getReadDay()<=number.intValue()){
             throw new ResultException("今日权限已用完，可以购买会员或升级权益");
         }

        return number.intValue();
    }

    private final RedisCache redisCache;

    @Override
    public void isReadNum(HttpServletRequest request) {
        Rule rule = ruleService.getById(1);
        Integer readDay = rule.getReadDay();
        String realIp = IpKit.getRealIp(request);
        String s = redisCache.get(TagConstants.READ_IP + realIp);
        Integer num=1;
        if(StrUtil.isNotBlank(s)){
            Integer convert = Convert.convert(Integer.class, s);
            if(convert >=readDay ){
                throw new ResultException("请登录查看");
            }
            num=convert+1;
        }
        redisCache.set(TagConstants.READ_IP + realIp,num.toString(), LocalDateUtils.getRemainSecondsOneDay(new Date()), TimeUnit.HOURS);
    }
}
